Skip to content

Conversation

@andykaylor
Copy link
Contributor

The code to read the "nobuiltins" attributes hasn't been implemented yet, but we were defaulting to the assumption that use of builtins is allowed for function calls that we recognize as standard C library calls and have builtin equivalents of. This change reverses that assumption so that when such calls are encountered, we just emit the call. This is a better default assumption, and since our builtin handling for these functions isn't implemented yet, it also allows us to compile more programs.

The code to read the "nobuiltins" attributes hasn't been implemented yet,
but we were defaulting to the assumption that use of builtins is allowed
for function calls that we recognize as standard C library calls and
have builtin equivalents of. This change reverses that assumption so that
when such calls are encountered, we just emit the call. This is a better
default assumption, and since our builtin handling for these functions
isn't implemented yet, it also allows us to compile more programs.
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Jun 13, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 13, 2025

@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)

Changes

The code to read the "nobuiltins" attributes hasn't been implemented yet, but we were defaulting to the assumption that use of builtins is allowed for function calls that we recognize as standard C library calls and have builtin equivalents of. This change reverses that assumption so that when such calls are encountered, we just emit the call. This is a better default assumption, and since our builtin handling for these functions isn't implemented yet, it also allows us to compile more programs.


Full diff: https://github.com/llvm/llvm-project/pull/144004.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+2-1)
  • (added) clang/test/CIR/CodeGen/libc.c (+55)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 5d04faf443b8d..b3b23eb41bfa3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1052,7 +1052,8 @@ CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {
 
     bool isPredefinedLibFunction =
         cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(builtinID);
-    bool hasAttributeNoBuiltin = false;
+    // Assume nobuiltins everywhere until we actually read the attributes.
+    bool hasAttributeNoBuiltin = true;
     assert(!cir::MissingFeatures::attributeNoBuiltin());
 
     // When directing calling an inline builtin, call it through it's mangled
diff --git a/clang/test/CIR/CodeGen/libc.c b/clang/test/CIR/CodeGen/libc.c
new file mode 100644
index 0000000000000..f65fe92cd36a0
--- /dev/null
+++ b/clang/test/CIR/CodeGen/libc.c
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+// Note: In the final implementation, we will want these to generate
+//       CIR-specific libc operations. This test is just a placeholder
+//       to make sure we can compile these to normal function calls
+//       until the special handling is implemented.
+
+void *memcpy(void *, const void *, unsigned long);
+void testMemcpy(void *dst, const void *src, unsigned long size) {
+  memcpy(dst, src, size);
+  // CHECK: cir.call @memcpy
+}
+
+void *memmove(void *, const void *, unsigned long);
+void testMemmove(void *src, const void *dst, unsigned long size) {
+  memmove(dst, src, size);
+  // CHECK: cir.call @memmove
+}
+
+void *memset(void *, int, unsigned long);
+void testMemset(void *dst, int val, unsigned long size) {
+  memset(dst, val, size);
+  // CHECK: cir.call @memset
+}
+
+double fabs(double);
+double testFabs(double x) {
+  return fabs(x);
+  // CHECK: cir.call @fabs
+}
+
+float fabsf(float);
+float testFabsf(float x) {
+  return fabsf(x);
+  // CHECK: cir.call @fabsf
+}
+
+int abs(int);
+int testAbs(int x) {
+  return abs(x);
+  // CHECK: cir.call @abs
+}
+
+long labs(long);
+long testLabs(long x) {
+  return labs(x);
+  // CHECK: cir.call @labs
+}
+
+long long llabs(long long);
+long long testLlabs(long long x) {
+  return llabs(x);
+  // CHECK: cir.call @llabs
+}

@llvmbot
Copy link
Member

llvmbot commented Jun 13, 2025

@llvm/pr-subscribers-clangir

Author: Andy Kaylor (andykaylor)

Changes

The code to read the "nobuiltins" attributes hasn't been implemented yet, but we were defaulting to the assumption that use of builtins is allowed for function calls that we recognize as standard C library calls and have builtin equivalents of. This change reverses that assumption so that when such calls are encountered, we just emit the call. This is a better default assumption, and since our builtin handling for these functions isn't implemented yet, it also allows us to compile more programs.


Full diff: https://github.com/llvm/llvm-project/pull/144004.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+2-1)
  • (added) clang/test/CIR/CodeGen/libc.c (+55)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 5d04faf443b8d..b3b23eb41bfa3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1052,7 +1052,8 @@ CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {
 
     bool isPredefinedLibFunction =
         cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(builtinID);
-    bool hasAttributeNoBuiltin = false;
+    // Assume nobuiltins everywhere until we actually read the attributes.
+    bool hasAttributeNoBuiltin = true;
     assert(!cir::MissingFeatures::attributeNoBuiltin());
 
     // When directing calling an inline builtin, call it through it's mangled
diff --git a/clang/test/CIR/CodeGen/libc.c b/clang/test/CIR/CodeGen/libc.c
new file mode 100644
index 0000000000000..f65fe92cd36a0
--- /dev/null
+++ b/clang/test/CIR/CodeGen/libc.c
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+// Note: In the final implementation, we will want these to generate
+//       CIR-specific libc operations. This test is just a placeholder
+//       to make sure we can compile these to normal function calls
+//       until the special handling is implemented.
+
+void *memcpy(void *, const void *, unsigned long);
+void testMemcpy(void *dst, const void *src, unsigned long size) {
+  memcpy(dst, src, size);
+  // CHECK: cir.call @memcpy
+}
+
+void *memmove(void *, const void *, unsigned long);
+void testMemmove(void *src, const void *dst, unsigned long size) {
+  memmove(dst, src, size);
+  // CHECK: cir.call @memmove
+}
+
+void *memset(void *, int, unsigned long);
+void testMemset(void *dst, int val, unsigned long size) {
+  memset(dst, val, size);
+  // CHECK: cir.call @memset
+}
+
+double fabs(double);
+double testFabs(double x) {
+  return fabs(x);
+  // CHECK: cir.call @fabs
+}
+
+float fabsf(float);
+float testFabsf(float x) {
+  return fabsf(x);
+  // CHECK: cir.call @fabsf
+}
+
+int abs(int);
+int testAbs(int x) {
+  return abs(x);
+  // CHECK: cir.call @abs
+}
+
+long labs(long);
+long testLabs(long x) {
+  return labs(x);
+  // CHECK: cir.call @labs
+}
+
+long long llabs(long long);
+long long testLlabs(long long x) {
+  return llabs(x);
+  // CHECK: cir.call @llabs
+}

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a reasonable assumption for now. THOUGH, I wonder if we'd be better off at one point instead to figure out which ones we DO know how to handle, and use the 'nobuiltin' as a fallback instead? That way we can exercise the builtin-code as it gets implemented.

@andykaylor andykaylor merged commit 36c710c into llvm:main Jun 13, 2025
9 of 10 checks passed
@andykaylor andykaylor deleted the cir-builtin-error branch June 13, 2025 16:43
tomtor pushed a commit to tomtor/llvm-project that referenced this pull request Jun 14, 2025
The code to read the "nobuiltins" attributes hasn't been implemented
yet, but we were defaulting to the assumption that use of builtins is
allowed for function calls that we recognize as standard C library calls
and have builtin equivalents of. This change reverses that assumption so
that when such calls are encountered, we just emit the call. This is a
better default assumption, and since our builtin handling for these
functions isn't implemented yet, it also allows us to compile more
programs.
akuhlens pushed a commit to akuhlens/llvm-project that referenced this pull request Jun 24, 2025
The code to read the "nobuiltins" attributes hasn't been implemented
yet, but we were defaulting to the assumption that use of builtins is
allowed for function calls that we recognize as standard C library calls
and have builtin equivalents of. This change reverses that assumption so
that when such calls are encountered, we just emit the call. This is a
better default assumption, and since our builtin handling for these
functions isn't implemented yet, it also allows us to compile more
programs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants